const generate = Symbol('generate')
const getArguments = Symbol('getArguments')

class Permission {
  constructor (user) {
    this.permission = { sessionToken: user.getSessionToken() }
  }

  /**
   * 类生成器
   * @param name {string} 类名
   * @param methods {array} 需要改写的方法
   * @returns {object} 改写后的类
   */
  [generate] (name, methods) {
    const _this = this
    let Temp = function () {
      Parse[name].apply(this, Array.from(arguments))
      // 改写原型链上的方法
      methods.forEach(function (method) {
        if (typeof Parse[name].prototype[method] === 'function') {
          Temp.prototype[method] = function () {
            console.log(method, _this[getArguments](arguments))
            return Parse[name].prototype[method].call(this, ..._this[getArguments](arguments))
          }
        }
      })
    }
    // 复制方法
    Temp = Object.assign(Temp, Parse[name])
    // 改写类上的方法
    methods.forEach(function (method) {
      if (typeof Parse[name][method] === 'function') {
        Temp[method] = function () {
          return Parse[name][method](..._this[getArguments](arguments))
        }
      }
    })
    Temp.prototype = Object.create(Parse[name].prototype)
    Temp.prototype.constructor = Parse[name]
    return Temp
  }

  /**
   * 获取函数的 arguments，根据传进来的参数，加上权限参数
   * @param args
   * @returns {Array}
   */
  [getArguments] (args) {
    const arr = Array.from(args)
    const lastArg = arr[arr.length - 1]  // 最后的参数
    let options = this.permission
    // 最后一位参数是否为 options
    if (lastArg && typeof lastArg === 'object' &&
      (lastArg.success || lastArg.error || lastArg.useMasterKey || lastArg.sessionToken)
    ) {
      options = Object.assign(options, arr.pop())
    }
    arr.push(options)
    return arr
  }
  getQuery () {
    return this[generate]('Query', ['count', 'find', 'first', 'get', 'each'])
  }
  getObject () {
    return this[generate]('Object', ['destroy', 'destroyAll', 'fetch', 'fetchAll', 'fetchAllIfNeeded', 'save', 'saveAll'])
  }
  getFile () {
    return this[generate]('File', ['save'])
  }
  getUser () {
    return this[generate]('User', ['_upgradeToRevocableSession', 'become', 'enableRevocableSession', 'logIn', 'requestPasswordReset', 'setEmail', 'setPassword', 'setUsername', 'signUp', 'save'])
  }
}
/**
 * 改写Parse, 在运行 define 的时候，在需要权限控制的地方加入权限控制
 */
const permissionParse = (() => {
  const Cloud = Object.assign({}, Parse.Cloud)  // 改写Cloud的define方法
  const newParse = Object.assign({}, Parse, {Cloud})  // 重新获得一个parse对象
  Cloud.define = (name, callback) => {
    return Parse.Cloud.define(name, (req, res) => {
      // 校验是否已经登录
      const user = req.user
      if (!user) {
        return res.error('请先登录')
      }
      const permission = new Permission(req.user)
      ;['Query', 'Object', 'File', 'User'].forEach((item) => {
        newParse[item] = permission[`get${item}`]()
      })
      callback && callback(req, res)
    })
  }
  return newParse
})()

module.exports = permissionParse
